﻿using SqlSugar;
using System;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace SageKing.Database.SqlSugar.Service;

/// <summary>
/// 用于数据库维护
/// </summary>
public class DbMaintenanceService : IDbMaintenanceService
{
    Dictionary<string, ISqlSugarClient> DBClientDic;

    public IDbMaintenanceService Me => this;

    public DbMaintenanceService()
    {
        DBClientDic = new Dictionary<string, ISqlSugarClient>();
    }

    /// <summary>
    /// 获取数据库表集合
    /// </summary>
    /// <returns></returns>
    [DisplayName("获取数据库表集合")]
    public async Task<List<TableOutput>> GetTableList(DBTypesEnum DbType, string connectionString, bool isCache = false)
    {
        var provider = GetSqlSugarClient(DbType, connectionString);

        var dbTableInfos = provider.DbMaintenance.GetTableInfoList(isCache)
            .Select(a => new TableOutput
            {
                TableName = a.Name,
                TableComment = a.Description,
                Type = (DBObjectTypeEnum)(int)a.DbObjectType,
            }).ToList();


        return await Task.FromResult(dbTableInfos);
    }

    /// <summary>
    /// 根据表名获取列集合
    /// </summary>
    /// <returns></returns>
    [DisplayName("根据表名获取列集合")]
    public List<ColumnOuput> GetColumnListByTableName([Required] string tableName, DBTypesEnum DbType, string connectionString)
    {
        var provider = GetSqlSugarClient(DbType, connectionString);

        return provider.DbMaintenance.GetColumnInfosByTableName(tableName).Select(u => new ColumnOuput
        {
            ColumnName = u.DbColumnName,
            IsPrimarykey = u.IsPrimarykey,
            DataType = u.DataType.ToString(),
            DBToNetType = ConvertDataType(u, provider.CurrentConnectionConfig.DbType),
            NetType = ConvertDataType(u, provider.CurrentConnectionConfig.DbType).GetDataStreamTypeEnum(),
            ColumnComment = u.ColumnDescription

        }).ToList();
    }

    /// <summary>
    /// 根据数据库类型来处理对应的数据字段类型
    /// </summary>
    /// <param name="dbColumnInfo"></param>
    /// <param name="dbType"></param>
    /// <returns></returns>
    public string ConvertDataType(DbColumnInfo dbColumnInfo, DbType dbType = DbType.Custom)
    {
        var dataType = dbType switch
        {
            DbType.Oracle => Me.ConvertDataType_OracleSQL(string.IsNullOrEmpty(dbColumnInfo.OracleDataType) ? dbColumnInfo.DataType : dbColumnInfo.OracleDataType, dbColumnInfo.Length, dbColumnInfo.Scale),
            DbType.PostgreSQL => Me.ConvertDataType_PostgreSQL(dbColumnInfo.DataType),
            _ => Me.ConvertDataType_Default(dbColumnInfo.DataType),
        };

        return dataType + (dbColumnInfo.IsNullable ? "?" : "");
    }

    private ISqlSugarClient GetSqlSugarClient(DBTypesEnum DbType, string connectionString)
    {
        var key = $"{DbType}_{connectionString}";

        if (!DBClientDic.TryGetValue(key, out var provider))
        {
            provider = new SqlSugarClient(new ConnectionConfig()
            {
                ConfigId = key,
                DbType = (DBType)DbType,
                ConnectionString = connectionString,
                IsAutoCloseConnection = true
            });

            DBClientDic[key] = provider;

        }
        return provider;
    }

}
